﻿using BlazorAdmin.Models;
using BlazorAdmin.Interface;
using BlazorAdmin.Web.Shared.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System.Net;

namespace BlazorAdmin.Web.Shared.Extensions
{
    public class LogMiddleWare
    {
        private ILog logService { get; set; }

        [Inject]
        private BootstrapAppContext? AppContext { get; set; }

        private readonly RequestDelegate next;

        public LogMiddleWare(RequestDelegate nextDelegate, ILog log)
        {
            next = nextDelegate;
            logService = log;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            var requestData = string.Empty;
            if (!string.IsNullOrWhiteSpace(context.Request.QueryString.Value))
                requestData = WebUtility.UrlDecode(context.Request.QueryString.Value);

            if (context.Request.HasFormContentType && context.Request.Form.Count > 0)
            {
                var data = new Dictionary<string, string>();
                foreach (var key in context.Request.Form.Keys)
                    data.Add(key, context.Request.Form[key]);
                requestData = JsonConvert.SerializeObject(data);
            }

            Log log = new()
            {
                RequestUser = AppContext?.LoginName,
                RequestUrl = context.Request.Path,
                RequestMethod = context.Request.Method,
                RequestData = requestData,
                RequestProtocol = context.Request.Protocol,
                ClientIP = context.Connection.RemoteIpAddress.MapToIPv4().ToString(),
                UserAgent = context.Request.Headers["User-Agent"].ToString(),
            };

            ThreadPool.QueueUserWorkItem(state => {
                if (logService != null) 
                    logService.OperateLog(log);
            });

            await next(context);
        }
    }

    public static class LogMiddleWareExtension
    {
        public static IApplicationBuilder UseLogMiddleWare(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<LogMiddleWare>();
        }
    }
}
